using SmartCommunity.Models;
using Mapster;
using Microsoft.EntityFrameworkCore;

namespace SmartCommunity.WebApi.Services.System
{
    /// <summary>
    /// 服务类：用户
    /// </summary>
    public class UserService : BaseService<UserEntity>
    {
        #region 构造函数
        protected readonly SCDBContext ctx;
        private readonly ConfigService configService;
        public UserService(SCDBContext ctx, ConfigService configService)
        {
            this.ctx = ctx;
            this.configService = configService;
        }
        #endregion

        #region 数据查询 
        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<PageResult<UserDto>> FindPagedList(UserQuery userQuery, Pager pager, LoginUser user)
        {
            if (!user.IsSuperAdmin)
            {
                userQuery.AddExpression(a => a.Username != AppConstants.SUPER_ADMIN);
            }
            var query = ctx.Users.AsNoTracking().Where(userQuery.GetQueryExpression());
            var pageData = await FindPagedList(query, pager, o => o.OrderByDescending(t => t.CreatedTime));
            return pageData.Map(o => o.Adapt<UserDto>());
        }

        /// <summary>
        /// 根据用户ID查询
        /// </summary>
        public async Task<UserDto> FindUserById(int userId)
        {
            var entity = await FindById(userId);
            return entity.Adapt<UserDto>();
        }

        /// <summary>
        /// 根据ID查询实体类
        /// </summary>
        private async Task<UserEntity> FindById(int id, bool includeRols = true)
        {
            var user = includeRols
                ? await ctx.Users.Include(a => a.Roles).SingleOrDefaultAsync(a => a.UserId == id)
                : await ctx.Users.SingleOrDefaultAsync(a => a.UserId == id);
            return user ?? throw new NotFoundException($"找不到指定的用户,Id:{id}");
        }
        #endregion

        #region 增 删 改
        /// <summary>
        /// 新增用户
        /// </summary>
        public async Task<UserDto> CreateUser(UserDto dto, LoginUser user)
        {
            // 新建对象
            var entity = new UserEntity();
            // 复制属性
            await CopyDtoToEntity(dto, entity, user, true);
            // 获取配置的初始密码
            var defPwd = await configService.GetConfigValue("system.init_password", "123456");
            entity.Password = defPwd;
            // 执行保存
            ctx.Users.Add(entity);
            await ctx.SaveChangesAsync();
            // 返回Dto
            return entity.Adapt<UserDto>();
        }

        /// <summary>
        /// 更新用户
        /// </summary>
        public async Task UpdateUser(UserDto dto, LoginUser user)
        {
            // 原始数据
            var entity = await FindById(dto.UserId);
            // 更新字段
            await CopyDtoToEntity(dto, entity, user, false);
            // 执行更新
            await ctx.SaveChangesAsync();
        }

        /// <summary>
        /// 复制dto属性到实体字段
        /// </summary>
        private async Task CopyDtoToEntity(UserDto dto, UserEntity entity, LoginUser user, bool isNew)
        {
            // 检查数据重复
            if (await ctx.Users.AnyAsync(a => a.UserId != dto.UserId && (a.Username == dto.Username || a.Nickname == dto.Nickname)))
            {
                throw new MessageException("当前已存在相同名或昵称的用户");
            }
            if (dto.Username == AppConstants.SUPER_ADMIN)
            {
                throw new MessageException("禁止修改超级管理员用户");
            }
            entity.Nickname = dto.Nickname;
            entity.Cellphone = dto.Cellphone;
            entity.Email = dto.Email ?? "";
            entity.Gender = dto.Gender ?? "O";
            entity.Disabled = dto.Disabled;

            entity.Roles = await ctx.Roles.Where(a => dto.RoleIds.Contains(a.RoleId)).ToListAsync();

            if (isNew)
            {
                entity.Username = dto.Username;

                entity.Status = UserStatus.Normal;
                entity.Avatar = "";
                entity.Remark = "";
            }
            // 记录操作人
            if (isNew)
            {
                entity.CreatedBy = user.Username;
                entity.CreatedTime = DateTime.Now;
            }
            entity.UpdatedBy = user.Username;
            entity.UpdatedTime = DateTime.Now;
        }

        /// <summary>
        /// 根据ID删除用户
        /// </summary>
        public async Task DeleteByIds(IEnumerable<int> ids, LoginUser user)
        {
            var lstData = await ctx.Users.Include(a => a.Roles).Where(a => ids.Contains(a.UserId)).ToListAsync();
            if (lstData.Count != ids.Count())
            {
                throw new MessageException("查询出的数据和传入的ID不匹配，请刷新后再试。");
            }
            // 判断是否能删除
            foreach (var entity in lstData)
            {
                if (entity.Username == user.Username)
                {
                    throw new MessageException("禁止删除当前操作用户。");
                }
                if (entity.Username == AppConstants.SUPER_ADMIN)
                {
                    throw new MessageException("禁止删除超级管理员用户");
                }
                entity.Roles.Clear();
                ctx.Users.Remove(entity);
            }
            // 提交事务
            await ctx.SaveChangesAsync();
        }
        #endregion

        #region 用户中心
        public async Task<UserDataDto> GetUserCenterData(int userId)
        {
            var entity = await FindById(userId, false);
            return new UserDataDto()
            {
                UserId = userId,
                Nickname = entity.Nickname,
                Cellphone = entity.Cellphone,
                Email = entity.Email,
                Avatar = entity.Avatar,
            };
        }
        /// <summary>
        /// 修改用数据
        /// </summary>
        public async Task UpdateUserData(UserDataDto dto, LoginUser user)
        {
            if (dto.UserId != user.GetUserData().UserId && !user.IsSuperAdmin)
            {
            }
            if (await ctx.Users.AnyAsync(a => a.UserId != dto.UserId && (a.Nickname == dto.Nickname)))
            {
                throw new MessageException("当前已存在相同昵称的用户");
            }
            var entity = await FindById(dto.UserId, false);
            entity.Nickname = dto.Nickname;
            entity.Cellphone = dto.Cellphone;
            entity.Email = dto.Email ?? "";
            entity.Avatar = dto.Avatar;
            //entity.Introduction = dto.Introduction;
            await ctx.SaveChangesAsync();
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        public async Task UpdatePassword(int userId, string oldPwd, string newPwd, LoginUser user)
        {
            if (userId != user.GetUserData().UserId && !user.IsSuperAdmin)
            {
                throw new MessageException("修改密码只能本人操作");
            }
            var entity = await FindById(userId, false);
            //if (!PasswordEncoder.Matches(oldPwd, entity.Password))
            if (oldPwd != entity.Password)
            {
                throw new MessageException("原密码验证不通过", MessageType.Error);
            }
            //TODO 验证复杂度？
            //entity.Password = PasswordEncoder.Encode(newPwd);
            entity.Password = newPwd;
            await ctx.SaveChangesAsync();
        }
        #endregion
    }
}
